package cursorn.web;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;

import java.util.Collection;
import java.util.Set;

/**
 * $author ted
 */
public class PageDependencies {
    private final Set<SortedStringHolder> jsPaths = Sets.newTreeSet();
    private final Set<SortedStringHolder> jsInits = Sets.newTreeSet();

    private final Set<SortedStringHolder> cssPaths = Sets.newTreeSet();

    public void addJsPath(String jsPath, int priority) {
        System.out.println("Adding js-path");
        jsPaths.add(new SortedStringHolder(jsPath, priority * 1000000 + jsPaths.size()));
    }

    public void addJsInit(String jsInit, int priority) {
        System.out.println("Adding js-init");
        jsInits.add(new SortedStringHolder(jsInit, priority * 1000000 + jsInits.size()));
    }

    public void addJsPath(String jsPath) {
        addJsPath(jsPath, 10);
    }

    public void addJsInit(String jsInit) {
        addJsInit(jsInit, 10);
    }

    public void addCssPath(String cssPath, int priority) {
        cssPaths.add(new SortedStringHolder(cssPath, priority * 1000000 + cssPaths.size()));
    }
    public void addCssPath(String cssPath) {
        addCssPath(cssPath, 10);
    }

    public Collection<String> getCssPaths() {
        return toStrings(cssPaths);
    }

    public Collection<String> getJsPaths() {
        Collection<String> strings = toStrings(jsPaths);
        System.out.println("Getting js paths: " + strings);
        return strings;
    }

    public Collection<String> getJsInits() {
        return toStrings(jsInits);
    }

    private Collection<String> toStrings(Collection<? extends SortedHolder> sortedHolders) {
        return Collections2.transform(sortedHolders, new Function<SortedHolder, String>() {
            @Override
            public String apply(SortedHolder sortedStringHolder) {
                return sortedStringHolder.getContent().toString();
            }
        });
    }

    private abstract static class SortedHolder<T> implements Comparable<SortedHolder> {
        private final T content;
        private final Integer priority;

        private SortedHolder(T content, Integer priority) {
            this.content = content;
            this.priority = priority;
        }

        protected T getContent() {
            return content;
        }

        @Override
        public int compareTo(SortedHolder o) {
            return priority.compareTo(o.priority);
        }

        @Override
        public String toString() {
            return "SortedHolder{" +
                    "content=" + content +
                    ", priority=" + priority +
                    '}';
        }
    }

    private static class SortedStringHolder extends SortedHolder<String> {
        private SortedStringHolder(String string, Integer priority) {
            super(string, priority);
        }

        public String getString() {
            return getContent();
        }
    }

    private static class SortedInitCssHolder extends SortedHolder<String> {
        private final boolean isOnlyForIe;
        private SortedInitCssHolder(String css, Integer priority, boolean isOnlyForIe) {
            super(css, priority);
            this.isOnlyForIe = isOnlyForIe;
        }

        public String getInitCss() {
            return getContent();
        }

        public boolean isOnlyForIe() {
            return isOnlyForIe;
        }
    }

}
